package org.rsbot.service;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Logger;
import org.rsbot.script.Script;
import org.rsbot.script.ScriptManifest;

public class FileScriptSource
  implements ScriptSource
{
  private final Logger log = Logger.getLogger(getClass().getSimpleName());
  private File file;

  public FileScriptSource(File paramFile)
  {
    this.file = paramFile;
  }

  public List<ScriptDefinition> list() {
    LinkedList localLinkedList = new LinkedList();
    if (this.file != null)
      if (this.file.isDirectory())
        try {
          ScriptClassLoader localScriptClassLoader1 = new ScriptClassLoader(this.file.toURI().toURL());
          for (File localFile : this.file.listFiles())
            if (isJar(localFile))
              load(new ScriptClassLoader(getJarUrl(localFile)), localLinkedList, new JarFile(localFile));
            else
              load(localScriptClassLoader1, localLinkedList, localFile, "");
        }
        catch (IOException localIOException1)
        {
        }
      else if (isJar(this.file))
        try {
          ScriptClassLoader localScriptClassLoader2 = new ScriptClassLoader(getJarUrl(this.file));
          load(localScriptClassLoader2, localLinkedList, new JarFile(this.file));
        }
        catch (IOException localIOException2)
        {
        }
    return localLinkedList;
  }

  public Script load(ScriptDefinition paramScriptDefinition) throws ServiceException {
    if (!(paramScriptDefinition instanceof FileScriptDefinition)) {
      throw new IllegalArgumentException("Invalid definition!");
    }
    FileScriptDefinition localFileScriptDefinition = (FileScriptDefinition)paramScriptDefinition;
    try {
      return (Script)localFileScriptDefinition.clazz.asSubclass(Script.class).newInstance(); } catch (Exception localException) {
    }
    throw new ServiceException(localException.toString());
  }

  private void load(ClassLoader paramClassLoader, LinkedList<ScriptDefinition> paramLinkedList, JarFile paramJarFile)
  {
    Enumeration localEnumeration = paramJarFile.entries();
    while (localEnumeration.hasMoreElements()) {
      JarEntry localJarEntry = (JarEntry)localEnumeration.nextElement();
      String str1 = localJarEntry.getName().replace('/', '.');
      String str2 = ".class";
      if ((str1.endsWith(str2)) && (!str1.contains("$")))
        load(paramClassLoader, paramLinkedList, str1.substring(0, str1.length() - str2.length()));
    }
  }

  private void load(ClassLoader paramClassLoader, LinkedList<ScriptDefinition> paramLinkedList, File paramFile, String paramString)
  {
    if (paramFile.isDirectory()) {
      if (!paramFile.getName().startsWith("."))
        for (File localFile : paramFile.listFiles())
          load(paramClassLoader, paramLinkedList, localFile, paramString + paramFile.getName() + ".");
    }
    else
    {
      ??? = paramString + paramFile.getName();
      String str = ".class";
      if ((((String)???).endsWith(str)) && (!((String)???).startsWith(".")) && (!((String)???).contains("!")) && (!((String)???).contains("$"))) {
        ??? = ((String)???).substring(0, ((String)???).length() - str.length());
        load(paramClassLoader, paramLinkedList, (String)???);
      }
    }
  }

  private void load(ClassLoader paramClassLoader, LinkedList<ScriptDefinition> paramLinkedList, String paramString) {
    Class localClass;
    try {
      localClass = paramClassLoader.loadClass(paramString);
    } catch (Exception localException) {
      this.log.warning(paramString + " is not a valid script and was ignored!");
      localException.printStackTrace();
      return;
    } catch (VerifyError localVerifyError) {
      this.log.warning(paramString + " is not a valid script and was ignored!");
      return;
    }
    if (localClass.isAnnotationPresent(ScriptManifest.class)) {
      FileScriptDefinition localFileScriptDefinition = new FileScriptDefinition(null);
      ScriptManifest localScriptManifest = (ScriptManifest)localClass.getAnnotation(ScriptManifest.class);
      localFileScriptDefinition.id = 0;
      localFileScriptDefinition.name = localScriptManifest.name();
      localFileScriptDefinition.authors = localScriptManifest.authors();
      localFileScriptDefinition.version = localScriptManifest.version();
      localFileScriptDefinition.keywords = localScriptManifest.keywords();
      localFileScriptDefinition.description = localScriptManifest.description();
      localFileScriptDefinition.clazz = localClass;
      localFileScriptDefinition.source = this;
      paramLinkedList.add(localFileScriptDefinition);
    }
  }

  private boolean isJar(File paramFile) {
    return (paramFile.getName().endsWith(".jar")) || (paramFile.getName().endsWith(".dat"));
  }

  private URL getJarUrl(File paramFile) throws IOException {
    URL localURL = paramFile.toURI().toURL();
    localURL = new URL("jar:" + localURL.toExternalForm() + "!/");
    return localURL;
  }

  private static class FileScriptDefinition extends ScriptDefinition
  {
    Class<?> clazz;
  }
}